package com.jixin.pay.manager.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.jixin.dao.DaoUtils;
import com.jixin.dao.model.JdPayDetailInfo;
import com.jixin.dao.model.PayRequestInfo;
import com.jixin.dao.service.PayInfoService;
import com.jixin.jdpay.JdPayConfigUtil;
import com.jixin.jdpay.JdPayParamUtils;
import com.jixin.jdpay.JdPayProvider;
import com.jixin.jdpay.request.SignJdPayRequest;
import com.jixin.jdpay.request.TradeJdPayRequest;
import com.jixin.pay.domain.JdPayResponse;
import com.jixin.pay.domain.PayResponse;
import com.jixin.pay.domain.PayResult;
import com.jixin.pay.enums.PayStatus;
import com.jixin.pay.enums.PayWay;
import com.jixin.pay.manager.JdPayManager;

public class JdPayManagerImpl implements JdPayManager {

	private static final Logger logger = LoggerFactory.getLogger("paylog");
	

	/**
	 * 签约网银在线支付
	 * @param tradeRequest
	 * @return
	 */
	@Override
	public PayResponse signJdPay(SignJdPayRequest tradeRequest){
		//签约
		Map<String, Object> params =  JdPayParamUtils.buildSignParam(tradeRequest);
		//处理交易结果
		JdPayResponse payResponse = new JdPayResponse();
		payResponse.setSuccess(false);
		payResponse.setBusinessNo(tradeRequest.getOrderNo());
		try{
			String reqString = JdPayConfigUtil.buildRequestParam(params);
			String response = JdPayProvider.process(JdPayConfigUtil.getCHARSET(), reqString);
			System.out.println(response);
			Map<String, String> resultMap = JdPayConfigUtil.operate(response);
			if(null != resultMap){
				payResponse.setDesc(resultMap.get("data.return.desc"));
				if("0000".equals(resultMap.get("data.return.code"))){
					payResponse.setSuccess(true);
				}
			}
			//记录签约请求信息
			PayRequestInfo payRequestInfo = buildPayRequestInfo(tradeRequest);
			payRequestInfo.setRequestInfo(JSONObject.toJSONString(params));
			payRequestInfo.setResultInfo(JSONObject.toJSONString(resultMap));
			payRequestInfo.setSuccess(payResponse.getSuccess());
			DaoUtils.getContext().getBean(PayInfoService.class).addPayRequestInfo(payRequestInfo);	
			//记录payId
			payResponse.setPayId(payRequestInfo.getPayId());
		}catch(Exception e){
			e.printStackTrace();
		}
		return payResponse;
	}
	
	/**
	 * 网银在线交易请求
	 * @param tradeRequest
	 * @return
	 */
	@Override
	public PayResponse tradeJdPay(TradeJdPayRequest tradeRequest){
		
		PayRequestInfo payRequestInfo = DaoUtils.getContext().getBean(PayInfoService.class).
				findPayRequestInfoBy(tradeRequest.getOrderNo(), tradeRequest.getPayId(), PayWay.JD_PAY.getCode());
		JdPayResponse payResponse = new JdPayResponse();
		payResponse.setSuccess(false);
		payResponse.setBusinessNo(payRequestInfo.getOrderNo());
		if(payRequestInfo.getAmount() != Integer.valueOf(tradeRequest.getAmount())){
			payResponse.setDesc("订单状态不一致");
			return payResponse;
		}
		JdPayDetailInfo detailInfo = null;
		try{
			Map<String, Object> params = JdPayParamUtils.buildTradeParam(payRequestInfo.getRequestInfo(), tradeRequest.getCode());
			String reqString = JdPayConfigUtil.buildRequestParam(params);
			String response = JdPayProvider.process(JdPayConfigUtil.getCHARSET(), reqString);
			Map<String, String> resultMap = JdPayConfigUtil.operate(response);
			System.out.println(resultMap);
			if(null != resultMap){
				payResponse.setDesc(resultMap.get("data.return.desc"));
				if("0000".equals(resultMap.get("data.return.code"))){
					payResponse.setSuccess(true);
				}
			}
			detailInfo = buildJdPayDetailInfo(params);
			detailInfo.setResultInfo(JSONObject.toJSONString(resultMap));
			detailInfo.setPayId(payRequestInfo.getPayId());
			detailInfo.setSuccess(payResponse.getSuccess());
		}catch(Exception e){
			e.printStackTrace();
		}
		
		//记录用户的支付详情信息
		try{
			DaoUtils.getContext().getBean(PayInfoService.class).addPayDetailInfo(detailInfo);
		}catch(Exception e){
			e.printStackTrace();
		}
		return payResponse;
	}
	
	/**
	 * 网银在线订单查询
	 * @param queryJdPayRequest
	 * @return
	 */
	@Override
	public PayResponse queryJdPay(String orderNo){
		Map<String, Object> params = new HashMap<>();
		params.put("trade_type", "Q");
		params.put("trade_id", orderNo);
		String reqString = JdPayConfigUtil.buildRequestParam(params);
		String response = JdPayProvider.process(JdPayConfigUtil.getCHARSET(), reqString);
		Map<String, String> resultMap = JdPayConfigUtil.operate(response);
		System.out.println(resultMap);
		JdPayResponse payResponse = new JdPayResponse();
		payResponse.setSuccess(false);
		payResponse.setBusinessNo(orderNo);
		try{
			if(null == resultMap || !"0000".equals(resultMap.get("data.return.code"))){
				return payResponse;
			}
			payResponse.setSuccess(true);
			payResponse.setBusinessNo(orderNo);
			
			payResponse.setDesc(resultMap.get("data.return.desc"));
			payResponse.setCode(resultMap.get("data.return.code"));
			return payResponse;
		}catch(Exception e){
			e.printStackTrace();
		}
		return payResponse;
	}
	
	
	/**
	 * 查询网银在线回调消息
	 * @param resp
	 * @return
	 */
	@Override
	public PayResult queryNotifyResp(String resp){
		Map<String, String> resultMap =  JdPayConfigUtil.operate(resp);
		System.out.println(resultMap);
		PayResult payResult = new PayResult();
		payResult.setStatus(PayStatus.FAIL);
		try{
			if(null == resultMap || !"0000".equals(resultMap.get("data.return.code"))){
				payResult.setStatus(getPayStatus(resultMap.get("data.trade.status")));
				return payResult;
			}
			payResult.setPayWay(PayWay.JD_PAY);
			payResult.setPayBizNo(resultMap.get("data.trade.id"));
			payResult.setRemark(resultMap.get("data.return.desc"));
			payResult.setStatus(getPayStatus(resultMap.get("data.trade.status")));
			payResult.setPaySerialNo("");
			return payResult;
		}catch(Exception e){
			e.printStackTrace();
		}
		return payResult;
	}
	
	/**
	 * 获取网银在线支付状态
	 * @param status
	 * @return
	 */
	public PayStatus getPayStatus(String status){
		PayStatus payStatus = PayStatus.FAIL;
		switch (status) {
			case "0":
				payStatus = PayStatus.SUCCESS;
				break;
			case "6":
				payStatus = PayStatus.CONFIRM;
				break;
			case "7":
				payStatus = PayStatus.FAIL;
				break;
			default:
				break;
		}
		return payStatus;
	}
	
	/**
	 * 构建支付请求记录
	 * @param request
	 * @return
	 */
	private PayRequestInfo buildPayRequestInfo(SignJdPayRequest request){
		PayRequestInfo payRequestInfo = new PayRequestInfo();
		payRequestInfo.setAmount(Integer.valueOf(request.getAmount()));
		payRequestInfo.setCreateTime(new Date());
		payRequestInfo.setOrderNo(request.getOrderNo());
		payRequestInfo.setPayId(UUID.randomUUID().toString());
		payRequestInfo.setPayWay(PayWay.JD_PAY.getCode());
		return payRequestInfo;
	}
	
	/**
	 * 构建订单支付详细信息
	 * @param params
	 * @return
	 */
	public JdPayDetailInfo buildJdPayDetailInfo(Map<String, Object> params){
		JdPayDetailInfo detailInfo = new JdPayDetailInfo();
		detailInfo.setBankCode((String) params.get("card_bank"));
		detailInfo.setBankNo((String) params.get("card_no"));
		detailInfo.setName((String) params.get("name"));
		detailInfo.setIdcard((String) params.get("card_idno"));
		detailInfo.setOrderNo((String) params.get("trade_id"));
		detailInfo.setPayDate((String) params.get("trade_date"));
		detailInfo.setPayTime((String) params.get("trade_time"));
		detailInfo.setAmount(Integer.valueOf((String) params.get("trade_amount")));
		detailInfo.setCreateTime(new Date());
		detailInfo.setRequestInfo(JSONObject.toJSONString(params));
		detailInfo.setPhone((String) params.get("card_phone"));
		return detailInfo;
	}
	
}
